package com.huajin.iot.monitor.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.huajin.iot.common.service.EsDataSource;
import com.fasterxml.jackson.databind.JsonNode;


import com.huajin.iot.common.utils.JsonUtils2;
import com.huajin.iot.monitor.domin.GatewayipDO;
import com.huajin.iot.monitor.service.GatewayipService;
import org.apache.http.HttpEntity;
import org.apache.http.entity.ContentType;
import org.apache.http.nio.entity.NStringEntity;
import org.apache.http.util.EntityUtils;
import org.elasticsearch.client.Response;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.io.IOException;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 从迪拜 es数据库中获取数据并存入昌平数据中心es
 * 
 * @author ke
 *
 */


@Service
public class EsServiceImpl {

	@Autowired
	EsDataSource esDataSource;
    @Autowired
    GatewayipService gatewayipService;

	private static final String  WARN_QUERY = "{ \"query\": {\"bool\": {\"must\": [ {\"range\": { \"@timestamp\": { \"gte\": \"%s\", \"lte\": \"%s\" } }},{\"bool\": {\"filter\": {\"term\": { \"logtype\": \"%s\" }} }} ]}} , \"aggs\": { \"aggs_time\": { \"date_histogram\": { \"field\": \"@timestamp\", \"interval\": \"%s\" } } } }";
    private static final String  WARN_LIST = "{ \"query\": {\"bool\": {\"must\": [ {\"range\": { \"@timestamp\": { \"gte\": \"%s\"} }},{\"bool\": {\"filter\": {\"term\": { \"logtype\": \"%s\" }} }} ]}} , \"sort\": [ { \"@timestamp\": { \"order\": \"desc\" } } ] }";
    private static final String  GATEWAY_BY_IP= "{ \"aggs\": { \"aggs_gateway\": { \"terms\": { \"field\": \"host.keyword\" } } } }";
    private static final String  WARN_BY_IP= "{ \"query\": {\"bool\": {\"filter\": {\"term\": { \"logtype\": \"%s\" }}}}, \"aggs\": { \"aggs_gateway\": { \"terms\": { \"field\": \"host.keyword\" } } } }";
    private static final String  WARN_BY_ASSET="{ \"query\": {\"bool\": {\"filter\": {\"term\": { \"logtype\": \"%s\" }}}}, \"aggs\": { \"aggs_gateway\": { \"terms\": { \"field\": \"custom_iotfactory.keyword\" } } } }";
    private static final String  WARN_QUERY_URL = "/syslog-16/_search?size=0";
    private static final String  WARN_LIST_URL = "/syslog-16/_search";
    private static final String   logtype = "365";
    /** 获取小时告警统计 */

    public Map<String, Object> get24HourCount() {
        // 开始时间  结束时间  logtype类型：实际是365，测试是1 分段单元hour
        String  query = String.format(WARN_QUERY,"now-24h","now",logtype,"hour");
        JSONObject res = JSON.parseObject(this.execQuery(query, WARN_QUERY_URL));
        JSONArray arr = res.getJSONObject("aggregations").getJSONObject("aggs_time").getJSONArray("buckets");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("res", arr);
        return map;
    }

    /** 获取星期告警统计 */

    public Map<String, Object> get1WeekCount() {
        // 开始时间  结束时间  logtype类型：实际是365，测试是1 分段单元week
        String  query = String.format(WARN_QUERY,"now-1w","now",logtype,"week");
        JSONObject res = JSON.parseObject(this.execQuery(query, WARN_QUERY_URL));
        JSONArray arr = res.getJSONObject("aggregations").getJSONObject("aggs_time").getJSONArray("buckets");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("res", arr);
        return map;
    }

    /** 获取月份告警统计 */
    public Map<String, Object> get12MonthCount() {
        // 开始时间  结束时间  logtype类型：实际是365，测试是1 分段单元month
        String  query = String.format(WARN_QUERY,"now-y","now",logtype,"month");
        JSONObject res = JSON.parseObject(this.execQuery(query, WARN_QUERY_URL));
        JSONArray arr = res.getJSONObject("aggregations").getJSONObject("aggs_time").getJSONArray("buckets");
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("res", arr);
        return map;
    }

    /** 获取告警事件列表 */
    //devid=0 date="2018/02/28 15:36:52" dname=themis logtype=365 pri=5 mod=asset_scan dsp_msg="设备下线IP:10.1.5.222"
    // devid=0 date="2018/01/31 14:37:26" dname=themis logtype=365 pri=1 mod=asset_scan dsp_msg="设备指纹改变!IP:6.6.6.207 MAC:00:1B:21:75:2B:92 OWER:Intel OS:Microsoft Windows 10 build 10074 改变成 IP:6.6.6.207 MAC:00:1B:21:75:2B:92 OWER:Intel OS:Microsoft Windows 10 10586 - 143"
    public Map<String, Object> get30MinWarnList() {
        //找到最近30分钟的告警  分段单元测试是 30M 实际是30m logtype类型：实际是365，测试是1
        String  query = String.format(WARN_LIST,"now-30M",logtype);
        JSONObject res = JSON.parseObject(this.execQuery(query,WARN_LIST_URL));
        JSONArray arr = res.getJSONObject("hits").getJSONArray("hits");
        List< Map<String, Object> > list = new ArrayList<>();
        for (int i=0;i<arr.size();i++) {
            JSONObject obj  = arr.getJSONObject(i).getJSONObject("_source");
            String regEx = "((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))";
            String  dsp_msg = obj.getString("dsp_msg");
            Pattern pattern = Pattern.compile(regEx);
            Matcher matcher = pattern.matcher(dsp_msg);
            String ip ="nokown";
            if (matcher.find()) {
                ip = matcher.group();
            }
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("time",obj.getString("@timestamp"));
            map.put("ip",ip);
            map.put("result",dsp_msg);
            if (dsp_msg.contains("指纹改变"))  {
                map.put("rank","3");
            }else if(dsp_msg.contains("新增")) {
                map.put("rank","2");
            }else {
                map.put("rank","1");
            }
            map.put("address","等资产列表完成查找");
            list.add(map);
        }
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("res", list);
        return map2;
    }

    /** 获取设备类型告警统计*/

    public Map<String, Object> getWarnByAsset() {
        String  query = String.format(WARN_BY_ASSET,logtype);
        JSONObject res = JSON.parseObject(this.execQuery(query,WARN_QUERY_URL));
        JSONArray arr  = res.getJSONObject("aggregations").getJSONObject("aggs_gateway").getJSONArray("buckets");
        Map<String, Object> map = new HashMap<String, Object>();
        for (int i=0;i<arr.size();i++) {
            String assetName=  arr.getJSONObject(i).getString("key");
            String doc_count =  arr.getJSONObject(i).getString("doc_count");
            map.put(assetName,doc_count);
        }
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("res", map);
        return map2;
    }

    /** 获取地域告警统计*/
    /** 根据ip 到资产表中获取地址信息 然后聚类*/
    public Map<String, Object> getWarnByArea() {
        String  query = String.format(WARN_BY_IP,logtype);
        JSONObject res = JSON.parseObject(this.execQuery(query,WARN_QUERY_URL));
        JSONArray arr  = res.getJSONObject("aggregations").getJSONObject("aggs_gateway").getJSONArray("buckets");
        Map<String, Object> map = new HashMap<String, Object>();
        for (int i=0;i<arr.size();i++) {
            String gatewayip =  arr.getJSONObject(i).getString("key");
            String doc_count =  arr.getJSONObject(i).getString("doc_count");
            map.put(gatewayip+ "=》位置",doc_count);
            // 将gatewayip 替换为地址信息重新计算数量
        }
        Map<String, Object> map2 = new HashMap<String, Object>();
        map2.put("res", map);
        return map2;
    }


    /** 需要改写成定时任务然后保存到网关表中*/
    public  Map<String, Object>  getGateWayIP() {
        JSONObject res = JSON.parseObject(this.execQuery(GATEWAY_BY_IP,WARN_QUERY_URL));
        JSONArray arr  = res.getJSONObject("aggregations").getJSONObject("aggs_gateway").getJSONArray("buckets");
        Set< String > set = new HashSet<>();
        for (int i=0;i<arr.size();i++) {
         String gatewayip =   arr.getJSONObject(i).getString("key");
         set.add(gatewayip);
        }
        for (String s:set) {
            try {
                GatewayipDO gatewayipDO = new GatewayipDO();
                gatewayipDO.setIp(s);
                System.out.println(gatewayipDO.getIp());
                gatewayipService.save(gatewayipDO);
            } catch (Exception e) {

            }
        }
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("res", set);
        return map;
    }





	/**
	 * 执行es查询语句，并返回json格式查询结果
	 * 
	 * @param query
	 *            json字符串格式的 查询语句
	 * @return
	 */
	private String execQuery(String query, String url) {
		HttpEntity httpEntity = new NStringEntity(query, ContentType.APPLICATION_JSON);
        String  respStr = null;
		int i = 0;
		// 考虑到国内外网络状况，当请求失败时重复尝试三次
		while (respStr == null && i++ < 3) {
			try {
				Response response = esDataSource.getEsClient().performRequest("POST", url,
						Collections.<String, String>emptyMap(), httpEntity);
				respStr = EntityUtils.toString(response.getEntity());

			} catch (IOException e) {
				//log.error(e.getMessage(), e);
			}
		}
        System.out.println(respStr);
		return respStr;
	}

//	/** 将数据存在能源搜索, 只尝试一次，失败跳过 */
//	public void saveEnergySearch(EnergyEntity energy) {
//
//		try {
//			HttpResponse<String> resp = Unirest.post(insertApi).header("ACCEPT", "application/json")
//					.header("Content-Type", "application/json").body(JsonUtils.toSnkeCaseJson(energy)).asString();
//			if (resp.getStatus() != HttpStatus.SC_OK) {
//				log.error("api insert failed! {}", energy.getDocid());
//				log.error("api response: {}", resp.getBody());
//			}
//		} catch (UnirestException | IOException e) {
//			log.error(e.getMessage(), e);
//		}
//
//	}
//
//	/** 将敏感数据存入敏感索引,以备接下来人工审查 */
//	public void saveSensitivity(EnergyEntity energy) {
//		StringBuilder stringBuilder = new StringBuilder();
//		String url = stringBuilder.append("/").append(sensitiviveIndex).append("/").append("doc").append("/")
//				.append(energy.getDocid()).toString();
//		try {
//			Response resp = esDataSource.getConsumerClient().performRequest("POST", url, Collections.emptyMap(),
//					new NStringEntity(JsonUtils.toSnkeCaseJson(energy), ContentType.APPLICATION_JSON));
//			if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_CREATED
//					|| resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//				EntityUtils.consumeQuietly(resp.getEntity());
//				return;
//			}
//			log.error("sensitivity insert failed! {}", energy.getDocid());
//			log.error("sensitivity elastic response: {}", EntityUtils.toString(resp.getEntity()));
//		} catch (IOException e) {
//			log.error(e.getMessage(), e);
//		}
//	}
//
//	/** 删除迪拜maxTime之前的所有新闻 */
//	public void deletePast(String maxTime) {
//		String deleteQuery = String.format(DELETE_QUERY, maxTime);
//		try {
//			Response resp = esDataSource.getFetchClient().performRequest("POST", "/bigdata/doc/_delete_by_query",
//					Collections.emptyMap(), new NStringEntity(deleteQuery, ContentType.APPLICATION_JSON));
//			if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
//				log.info("sensitivity delete success! {}", maxTime);
//				EntityUtils.consumeQuietly(resp.getEntity());
//				return;
//			}
//			log.error("sensitivity delete failed! {}", EntityUtils.toString(resp.getEntity()));
//		} catch (IOException e) {
//			log.error(e.getMessage(), e);
//		}
//	}

}
